package cn.aiseminar.aisinterphone;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;

public class VoiceActivity extends Activity {
	private BluetoothPhoneService mPhoneService = null;
	// for audio recording in local
	private AudioRecord mRecorder = null;
	private boolean mInRecording = false;
	private int mRecordBufferSize = 0;
	private static final int mSampleRate = 44100;
	private static final int mRecordChannel = AudioFormat.CHANNEL_IN_MONO;
	private static final int mTrackChannel = AudioFormat.CHANNEL_OUT_MONO;
	private static final int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
	// for play audio data from remote
	private AudioTrack mPlayer = null;
	
	@SuppressLint("HandlerLeak")
	private final Handler mMessageHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what)
			{
			case BluetoothPhoneService.MSG_DEVICE_CONNECT_FAILED:
				String errorMsg = (String) msg.obj;
				Toast.makeText(VoiceActivity.this, errorMsg, Toast.LENGTH_LONG).show();
				VoiceActivity.this.finish();
				break;
			case BluetoothPhoneService.MSG_CONTENT_READED:
				byte[] readBuf = (byte[]) msg.obj;
				int readBytes = msg.arg1;
				if (null != mPlayer)
				{
					mPlayer.write(readBuf, 0, readBytes);
				}
				break;
			case BluetoothPhoneService.MSG_CONTENT_WRITED:
				break;
			case BluetoothPhoneService.MSG_DEVICE_DISCONNECTED:
				Toast.makeText(VoiceActivity.this, R.string.msg_device_disconnected, Toast.LENGTH_LONG).show();
				VoiceActivity.this.finish();
				break;
			}
			super.handleMessage(msg);
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);			
        this.setContentView(R.layout.voice_activity);
        
        mPhoneService = BluetoothPhoneService.getBluetoothPhoneService();
        mPhoneService.setMsgHandler(mMessageHandler);
        
        int trackBufferSize = AudioTrack.getMinBufferSize(mSampleRate, mTrackChannel, mAudioFormat);
		mPlayer = new AudioTrack(AudioManager.STREAM_MUSIC, mSampleRate, mTrackChannel, mAudioFormat, trackBufferSize, AudioTrack.MODE_STREAM);
		
		mRecordBufferSize = AudioRecord.getMinBufferSize(mSampleRate, mRecordChannel, mAudioFormat);
		mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, mSampleRate, mRecordChannel, mAudioFormat, mRecordBufferSize);
        
        ImageButton recordBtn = (ImageButton)this.findViewById(R.id.btnSpeaking);
        recordBtn.setOnTouchListener(new View.OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				int action = event.getActionMasked();
				switch (action)
				{
				case MotionEvent.ACTION_DOWN:
					onBtnRecord(true);
					break;
				case MotionEvent.ACTION_UP:
					onBtnRecord(false);
					break;
				}
				return false;
			}
		});
	}
		
	@Override
	protected void onPause() {
		super.onPause();
		
		if (null != mPlayer)
		{
			mPlayer.pause();
		}
	}

	@Override
	protected void onStop() {
		mPhoneService.stopTransferData();
		mPlayer.stop();
		super.onStop();
	}

	@Override
	protected void onStart() {
		super.onStart();
		if (null != mPlayer)
		{
			mPlayer.play();
		}
	}

	private void onBtnRecord(boolean start)
	{
		if (start)
		{
			mInRecording = true;
			AudioRecordThread recordThread = new AudioRecordThread();
			recordThread.start();
		}
		else
		{
			mInRecording = false;
		}
	}
	
	class AudioRecordThread extends Thread
	{		
		@Override
		public void run() {
			try
			{
				byte[] buffer = new byte[mRecordBufferSize];
				mRecorder.startRecording();
				while (mInRecording)
				{
					int readSize = mRecorder.read(buffer, 0, mRecordBufferSize);
					byte[] sendBuffer = new byte[readSize];
					System.arraycopy(buffer, 0, sendBuffer, 0, readSize);
					mPhoneService.sendDataToRemote(sendBuffer, 0, readSize);
				}
				mRecorder.stop();			
			}
			catch (Throwable t)
			{
				t.printStackTrace();
			}
		}		
	}
}
